\chapter{ILP32 Programming Model\label{x32}}

"x32" is commonly used to refer to \xARCH ILP32 programming model.

\section{Parameter Passing}
When a value of pointer type is returned or passed in a register, bits 32
to 63 shall be zero.

\section{Address Space}

ILP32 binaries reside in the lower 32 bits of the 64-bit virtual
address space and all addresses are 32 bits in size.  They should conform
to \textindex{small code model} or
\textindex{small position independent code model} (\textindex{PIC})
described in Section \ref{models}.

\section{Thread-Local Storage Support}

ILP32 Thread-Local Storage (TLS) support is based on LP64 TLS
implementation with some modifications.

\subsection{Global Thread-Local Variable}

For a global thread-local variable x:

\begin{verbatim}
extern __thread int x;
\end{verbatim}

\begin{description}
\item[\textindex{General Dynamic Model}]
  Load address of \code{x} into \reg{rax}

\begin{table}[H]
\Hrule
\caption{General Dynamic Model Code Sequence}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{LP64} & \multicolumn{3}{c}{ILP32} \\
\hline
0x00 & .byte & 0x66			& 0x00 & leaq  & x@tlsgd(\%rip),\%rdi \\
0x01 & leaq  & x@tlsgd(\%rip),\%rdi	& 0x07 & .word & 0x6666 \\
0x08 & .word & 0x6666			& 0x09 & rex64 & \\
0x0a & rex64 &				& 0x0a & call  & \_\_tls\_get\_addr@plt \\
0x0b & call  & \_\_tls\_get\_addr@plt	&      &       & \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

In TLSDESC code sequence, \code{leal} instruction must be encoded with
\code{rex} prefix even if it isn't required by destination register.
If the \code{leal} encoding has a variable length, linker can't tell
where it starts and can't safely perform GDesc -> IE/LE optimization.

\begin{table}[H]
\Hrule
\caption{General Dynamic Model Code Sequence with TLSDESC}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{LP64} & \multicolumn{3}{c}{ILP32} \\
\hline
0x00 & leaq & x@tlsdesc(\%rip),\%rax & 0x00 & rex leal  & x@tlsdesc(\%rip),\%eax \\
0x07 & call & *x@tlsdesc((\%rax) & 0x07 & call & *x@tlsdesc(\%eax) \\
0x08 & add & \%fs:0x0,\%eax & 0x09 & add & \%fs:0x0,\%eax \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\item[\textindex{Initial Exec Model}]
  Load address of \code{x} into \reg{rax}.  Instruction \code{addl}
  must be encoded with \code{rex} prefix even if it isn't required by
  destination register.  Otherwise linker can't safely perform IE -> LE
  optimization.

\begin{table}[H]
\Hrule
\caption{Initial Exec Model Code Sequence}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{LP64} & \multicolumn{3}{c}{ILP32} \\
\hline
0x00 & movq & \%fs:0,\%rax		& 0x00 & movl & \%fs:0,\%eax \\
0x09 & addq & x@gottpoff(\%rip),\%rax	& 0x08 & rex addl & x@gottpoff(\%rip),\%eax \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\item[\textindex{Initial Exec Model, II}]
  Load value of \code{x} into \reg{edi}.  \code{\%fs:(\%eax)} memory
  operand can't be used for ILP32 since its effective address is the base
  address of \code{\%fs} + value of \reg{eax} zero-extended to a 64-bit
  result, which is incorrect with negative value in \reg{eax}.

\begin{table}[H]
\Hrule
\caption{Initial Exec Model Code Sequence, II}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{LP64} & \multicolumn{3}{c}{ILP32} \\
\hline
0x00 & movq & x@gottpoff(\%rip),\%rax	& 0x00 & movq & x@gottpoff(\%rip),\%rax \\
0x07 & movl & \%fs:(\%rax),\%edi	& 0x07 & movl & \%fs:(\%rax),\%edi \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\end{description}

\subsection{Static Thread-Local Variable}

For a static thread-local variable x:

\begin{verbatim}
static __thread int x;
\end{verbatim}

\begin{description}
\item[\textindex{Local Dynamic Model}]
  Load address of \code{x} into \reg{rax}

\begin{table}[H]
\Hrule
\caption{Local Dynamic Model Code Sequence With Lea}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{LP64} & \multicolumn{3}{c}{ILP32} \\
\hline
0x00 & leaq  & x@tlsld(\%rip),\%rdi	& 0x00 & leaq & x@tlsld(\%rip),\%rdi\\
0x07 & call  & \_\_tls\_get\_addr@plt	& 0x07 & call & \_\_tls\_get\_addr@plt\\
0x0c & leaq  & x@dtpoff(\%rax),\%rax	& 0x0c & leal & x@dtpoff(\%rax),\%eax\\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

or

\begin{table}[H]
\Hrule
\caption{Local Dynamic Model Code Sequence With Add}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{LP64} & \multicolumn{3}{c}{ILP32} \\
\hline
0x00 & leaq  & x@tlsld(\%rip),\%rdi	& 0x00 & leaq & x@tlsld(\%rip),\%rdi\\
0x07 & call  & \_\_tls\_get\_addr@plt	& 0x07 & call & \_\_tls\_get\_addr@plt\\
0x0c & addq  & \$x@dtpoff,\%rax		& 0x0c & addl & \$x@dtpoff,\%eax\\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

For code sequence with TLSDESC, local dynamic model is similar to general
dynamic model.  The same encoding requirement for \code{leal} instruction
also applies.

\begin{table}[H]
\Hrule
\caption{General Dynamic Model Code Sequence with TLSDESC}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{LP64} & \multicolumn{3}{c}{ILP32} \\
\hline
0x00 & leaq & x@tlsdesc(\%rip),\%rax & 0x00 & rex leal  & x@tlsdesc(\%rip),\%eax \\
0x07 & call & *x@tlsdesc((\%rax) & 0x07 & call & *x@tlsdesc(\%eax) \\
0x08 & add & \%fs:0x0,\%eax & 0x09 & add & \%fs:0x0,\%eax \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\item[\textindex{Local Dynamic Model, II}]
  Load value of \code{x} into \reg{edi}

\begin{table}[H]
\Hrule
\caption{Local Dynamic Model Code Sequence, II}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{LP64} & \multicolumn{3}{c}{ILP32} \\
\hline
0x00 & movq & \%fs:0,\%rax		& 0x00 & movl & \%fs:0,\%eax \\
0x09 & movl & x@dtpoff(\%rax),\%edi	& 0x08 & movl & x@dtpoff(\%rax),\%edi \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\item[\textindex{Local Exec Model}]
  Load address of \code{x} into \reg{rax}

\begin{table}[H]
\Hrule
\caption{Local Exec Model Code Sequence With Lea}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{LP64} & \multicolumn{3}{c}{ILP32} \\
\hline
0x00 & movq & \%fs:0,\%rax		& 0x00 & movl & \%fs:0,\%eax \\
0x09 & leaq & x@tpoff(\%rax),\%rax	& 0x08 & leal & x@tpoff(\%rax),\%eax \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

or

\begin{table}[H]
\Hrule
\caption{Local Exec Model Code Sequence With Add}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{LP64} & \multicolumn{3}{c}{ILP32} \\
\hline
0x00 & movq & \%fs:0,\%rax		& 0x00 & movl & \%fs:0,\%eax \\
0x09 & addq & \$x@tpoff,\%rax		& 0x08 & addl & \$x@tpoff,\%eax \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\item[\textindex{Local Exec Model, II}]
  Load value of \code{x} into \reg{edi}

\begin{table}[H]
\Hrule
\caption{Local Exec Model Code Sequence, II}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{LP64} & \multicolumn{3}{c}{ILP32} \\
\hline
0x00 & movq & \%fs:0,\%rax		& 0x00 & movl & \%fs:0,\%eax \\
0x09 & movl & x@tpoff(\%rax),\%edi	& 0x08 & movl & x@tpoff(\%rax),\%edi \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\item[\textindex{Local Exec Model, III}]
  Load value of \code{x} into \reg{edi}

\begin{table}[H]
\Hrule
\caption{Local Exec Model Code Sequence, III}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{LP64} & \multicolumn{3}{c}{ILP32} \\
\hline
0x00 & movl & \%fs:x@tpoff,\%edi	& 0x00 & movl & \%fs:x@tpoff,\%edi \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\end{description}

\subsection{TLS Linker Optimization}

\begin{description}
\item[\textindex{General Dynamic To Initial Exec}]
  Load address of \code{x} into \reg{rax}

\begin{table}[H]
\Hrule
\caption{GD -> IE Code Transition}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{GD} & \multicolumn{3}{c}{IE} \\
\hline
0x00 & leaq  & x@tlsgd(\%rip),\%rdi	& 0x00 & movl  & \%fs:0, \%eax \\
0x07 & .word & 0x6666			& 0x08 & addq  & x@gottpoff(\%rip),\%rax\\
0x09 & rex64 &				&      &       & \\
0x0a & call  & \_\_tls\_get\_addr@plt	&      &       & \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\begin{table}[H]
\Hrule
\caption{GDesc -> IE Code Transition}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{GDesc} & \multicolumn{3}{c}{LE} \\
\hline
0x00 & rex leal & x@tlsdes(\%rip),\%eax	& 0x00 & rex movl & x@gottpoff(\%rip), \%eax \\
0x07 & call & *foo@TLSCALL(\%eax) & 0x07 & nopl & (\%rax) \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\begin{table}[H]
\Hrule
\caption{GD -> LE Code Transition}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{GD} & \multicolumn{3}{c}{LE} \\
\hline
0x00 & leaq  & x@tlsgd(\%rip),\%rdi	& 0x00 & movl  & \%fs:0, \%eax \\
0x07 & .word & 0x6666			& 0x08 & leal  & x@tpoff(\%rax),\%eax\\
0x09 & rex64 &				&      &       & \\
0x0a & call  & \_\_tls\_get\_addr@plt	&      &       & \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\begin{table}[H]
\Hrule
\caption{GDesc -> LE Code Transition}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{GDesc} & \multicolumn{3}{c}{LE} \\
\hline
0x00 & rex leal & x@tlsdes(\%rip),\%eax	& 0x00 & rex movl & \$x@tpoff, \%eax \\
0x07 & call & *foo@TLSCALL(\%eax) & 0x07 & nopl & (\%rax) \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\item[\textindex{Initial Exec To Local Exec}]
  Load address of \code{x} into \reg{rax}

\begin{table}[H]
\Hrule
\caption{IE -> LE Code Transition With Lea}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{IE} & \multicolumn{3}{c}{LE} \\
\hline
0x00 & movl & \%fs:0,\%eax		& 0x00 & movl & \%fs:0,\%eax \\
0x08 & rex addl & x@gottpoff(\%rip),\%eax	& 0x08 & rex leal & x@tpoff(\%rax),\%eax \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

or

\begin{table}[H]
\Hrule
\caption{IE -> LE Code Transition With Add}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{IE} & \multicolumn{3}{c}{LE} \\
\hline
0x00 & movl & \%fs:0,\%r12d		& 0x00 & movl & \%fs:0,\%r12d \\
0x09 & addl & x@gottpoff(\%rip),\%r12d	& 0x09 & addl & \$x@tpoff,\%r12d \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\item[\textindex{Initial Exec To Local Exec, II}]
  Load value of \code{x} into \reg{edi}.

\begin{table}[H]
\Hrule
\caption{IE -> LE Code Transition, II}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{IE} & \multicolumn{3}{c}{LE} \\
\hline
0x00 & movq & x@gottpoff(\%rip),\%rax	& 0x00 & movq & x@tpoff,\%rax \\
0x07 & movl & \%fs:(\%rax),\%edi	& 0x07 & movl & \%fs:(\%rax),\%edi \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\item[\textindex{Local Dynamic to Local Exec}]
  Load address of \code{x} into \reg{rax}

\begin{table}[H]
\Hrule
\caption{LD -> LE Code Transition With Lea}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{LD} & \multicolumn{3}{c}{LE} \\
\hline
0x00 & leaq  & x@tlsld(\%rip),\%rdi	& 0x00 & nopl & 0x0(\%rax) \\
0x07 & call  & \_\_tls\_get\_addr@plt	& 0x04 & movl & \%fs:0,\%eax\\
0x0c & leal  & x@dtpoff(\%rax),\%eax	& 0x0c & leal & x@tpoff(\%rax),\%eax\\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

or

\begin{table}[H]
\Hrule
\caption{LD -> LE Code Transition With Add}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{LD} & \multicolumn{3}{c}{LE} \\
\hline
0x00 & leaq  & x@tlsld(\%rip),\%rdi	& 0x00 & nopl & 0x0(\%rax) \\
0x07 & call  & \_\_tls\_get\_addr@plt	& 0x04 & movl & \%fs:0,\%eax\\
0x0c & addq  & \$x@dtpoff,\%rax		& 0x0c & addl & \$x@tpoff,\%eax\\
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\item[\textindex{Local Dynamic To Local Exec, II}]
  Load value of \code{x} into \reg{edi}.

\begin{table}[H]
\Hrule
\caption{LD -> LE Code Transition, II}
\begin{center}
\small\code{
\begin{tabular}{lll|lll}
\multicolumn{3}{c}{LD} & \multicolumn{3}{c}{LE} \\
0x00 & leaq  & x@tlsld(\%rip),\%rdi	& 0x00 & nopl & 0x0(\%rax) \\
0x07 & call  & \_\_tls\_get\_addr@plt	& 0x04 & movl & \%fs:0,\%eax\\
0x0c & movl  & x@dtpoff(\%rax),\%eax	& 0x0c & movl & x@tpoff(\%rax),\%eax\\
\hline
\end{tabular}
}
\end{center}
\Hrule
\end{table}

\end{description}

\section{Kernel Support}
Kernel should limit stack and addresses returned from system calls
bewteen $0x00000000$ to $0xffffffff$.

\section{Coding Examples}

Although ILP32 binaries run in the 64-bit mode, not all 64-bit instructions
are supported. This section discusses example code sequences for
fundamental operations which are different from the 64-bit mode.

\subsection{Indirect Branch}

Since indirect branch via memory loads a 64-bit address at the memory
location, it is not supported in ILP32.  Indirect branch via register
should be used instead.  The 32-bit address from memory is loaded into
the lower 32 bits of a register, which will automatically zero-extend
the upper 32 bits of the register.  Then the indirect call can be
performed via the 64-bit register. 

\begin{table}[H]
\Hrule
\caption{Indirect Branch}
\begin{center}
\code{
\begin{tabular}{ll|ll}
\multicolumn{2}{c}{LP64} & \multicolumn{2}{c}{ILP32} \\
\hline
call & *\%rax          & call & *\%rax \\
\hline
call & *func\_p(\%rip) & movl & func\_p(\%rip), \%eax \\
     &                 & call & *\%rax \\
\hline
call & *func\_p        & movl & func\_p, \%eax \\
     &                 & call & *\%rax \\
\hline
jmp  & *\%rax          & jmp  & *\%rax \\
\hline
jmp  & *func\_p(\%rip) & movl & func\_p(\%rip), \%eax \\
     &                 & jmp  & *\%rax \\
\hline
jmp  & *func\_p        & movl & func\_p, \%eax \\
     &                 & jmp  & *\%rax \\
\end{tabular}
}
\end{center}
\Hrule
\end{table}
